package org.hackystat.devcathlon.ui.page.matches.manage.matchpanel;

import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.wicket.util.tester.FormTester;
import org.apache.wicket.util.tester.WicketTester;
import org.hackystat.devcathlon.configuration.ConfigurationManager;
import org.hackystat.devcathlon.engine.event.Event;
import org.hackystat.devcathlon.engine.event.impl.BuildBeforeCommit;
import org.hackystat.devcathlon.engine.match.MatchManager;
import org.hackystat.devcathlon.engine.team.Team;
import org.hackystat.devcathlon.engine.team.TeamManager;
import org.hackystat.devcathlon.engine.test.DevcathlonTestHelper;
import org.hackystat.devcathlon.ui.DevcathlonApplication;
import org.hackystat.devcathlon.ui.page.matches.MatchesPage;
import org.hackystat.devcathlon.ui.page.matches.manage.MatchesManagePage;
import org.hackystat.devcathlon.ui.page.matches.manage.matchconfigurationpanel.
MatchConfigurationPage;
import org.hackystat.devcathlon.ui.page.matches.manage.matchdeletepanel.MatchDeletePage;
import org.hackystat.devcathlon.ui.page.teams.profile.TeamsProfile;
import org.hackystat.sensorbase.resource.projects.jaxb.Project;
import org.hackystat.utilities.tstamp.Tstamp;
import org.junit.Before;
import org.junit.Test;

/**
 * This is the test class for the match panel.
 * 
 * @author robin
 *
 */
public class TestMatchPanel extends DevcathlonTestHelper {

  /** The actual build and commit interval. */
  private int buildCommitInterval = 10;
  /** The actual commit streak threshold. */
  private int streakThreshold = 10;
  /** The actual commit streak threshold. */
  private int bonusWeight = 10;

  private String teamName1 = "TestTeam1";
  private String teamOwner1 = "admin";
  private String member1a = "Member1a";
  private String member1b = "Member1b";
  private String teamName2 = "TestTeam2";
  private String teamOwner2 = "TeamOwner2";
  private String member2a = "Member2a";
  private String member2b = "Member2b";
  /** Instance of an team. */
  Team team1;
  /** Instance of an team. */
  Team team2;
  /** List of events for a match. */
  private List<Event> events = new ArrayList<Event>();
  /** Team to project hash map. */
  Map<Team, Project> teams2projects = new HashMap<Team, Project>();
  /** Sensor base host URL. */
  private String sensorBaseHost = "http://localhost:9976/sensorbase/";
  /** Daily project data host URL. */
  private String dailyProjectDataHost = "http://localhost:9977/dailyprojectdata/";
  /** Instance of DevcathlonApplication. */
  private DevcathlonApplication devcathlonApplication;
  /** Instance of WicketTester. */
  private WicketTester tester;
  String location = "org.hackystat.devcathlon.engine.event.impl.BuildBeforeCommit";
  
  /**
   * Sets up a Devcathlon Configuration for testing.
   * 
   * @throws Exception If there are any errors.
   */
  @Before
  public void setUp() throws Exception {
    String eventName = BuildBeforeCommit.eventName;
    ConfigurationManager configManager = ConfigurationManager.getInstance();
    configManager.setBaseScoreWeight(eventName, 10);
    configManager.getConfiguration(eventName);
    configManager.setWakeupInterval(eventName, 60);
    configManager.setEventLocation(eventName, location);
    configManager.addProperty(eventName, BuildBeforeCommit.buildCommitKey, String
        .valueOf(buildCommitInterval));
    configManager.addProperty(eventName, BuildBeforeCommit.upperThresholdKey, String
        .valueOf(streakThreshold));
    configManager.addProperty(eventName, BuildBeforeCommit.meetThresholdKey, String
        .valueOf(bonusWeight));

    // Create the teams.
    team1 = makeTeamAndInvites(teamName1, teamOwner1, member1a, member1b);
    TeamManager.getInstance().getTeam(teamName1).setProjectName(teamName1);
    team2 = makeTeamAndInvites(teamName2, teamOwner2, member2a, member2b);
    TeamManager.getInstance().getTeam(teamName2).setProjectName(teamName2);
    
    // Create the projects.
    Project project1 = getProject(teamOwner1, teamName1);
    Project project2 = getProject(teamOwner2, teamName2);
    
    events.add(new BuildBeforeCommit());
    teams2projects.put(team1, project1);
    teams2projects.put(team2, project2);
    XMLGregorianCalendar now = Tstamp.makeTimestamp();
    XMLGregorianCalendar startDate = Tstamp.incrementDays(now, 2);
    XMLGregorianCalendar endDate = Tstamp.incrementDays(startDate, 2);
    // Create a pending match.
    MatchManager.getInstance().addMatch("Test 1", startDate, endDate, teams2projects, events);
    //Completed Match start and end dates.
    XMLGregorianCalendar startCompDate = Tstamp.incrementDays(now, -3);
    XMLGregorianCalendar endCompDate = Tstamp.incrementDays(now, -1);
    // Create a completed match.
    MatchManager.getInstance().addMatch("Test 3", startCompDate, endCompDate, 
        teams2projects, events);
    // Create an on going match.
    MatchManager.getInstance().addMatch("Test 2", startCompDate, endDate, teams2projects, events);
    devcathlonApplication = new DevcathlonApplication(dailyProjectDataHost, sensorBaseHost);
    tester = new WicketTester(devcathlonApplication);
  }
  
  /**
   * Test the match panel and all links.
   * @throws Exception If there are any errors.
   */
  @Test
  public void testMatchPanel() throws Exception {
    tester.setupRequestAndResponse();
    tester.startPage(devcathlonApplication.getHomePage());
    tester.assertRenderedPage(devcathlonApplication.getHomePage());

    FormTester formTester = tester.newFormTester("loginForm");
    formTester.setValue("user", "admin@hackystat.org");
    formTester.setValue("password", "admin@hackystat.org");
    formTester.submit();
    
    tester.startPage(MatchesManagePage.class);
    tester.assertRenderedPage(MatchesManagePage.class);
    tester.assertContains("On Going");
    tester.assertContains("Completed");
    tester.assertContains("Pending");
    
    // Test Match detail link.
    tester.clickLink("matchpanel:ItemList:1:MatchLink");
    tester.assertRenderedPage(MatchConfigurationPage.class);
    
    assertNotNull("wicket tag found", tester.getTagByWicketId("StatusLabel"));
    
    // Navigate back to start page.
    tester.clickLink("MatchesLink");
    tester.assertRenderedPage(MatchesPage.class);
    tester.clickLink("MatchesManageLink");
    tester.assertRenderedPage(MatchesManagePage.class);
    
    // Test team link.
    tester.clickLink("matchpanel:ItemList:1:Team1Row:Team1Link");
    tester.assertRenderedPage(TeamsProfile.class);
    
    // Navigate back to start page.
    tester.clickLink("MatchesLink");
    tester.assertRenderedPage(MatchesPage.class);
    tester.clickLink("MatchesManageLink");
    tester.assertRenderedPage(MatchesManagePage.class);
    
    // Test team link.
    tester.clickLink("matchpanel:ItemList:1:Team2Row:Team2Link");
    tester.assertRenderedPage(TeamsProfile.class);
    
    // Navigate back to start page.
    tester.clickLink("MatchesLink");
    tester.assertRenderedPage(MatchesPage.class);
    tester.clickLink("MatchesManageLink");
    tester.assertRenderedPage(MatchesManagePage.class);
    
    // Test delete match link.
    tester.clickLink("matchpanel:ItemList:1:deleteMatchLink");
    tester.assertRenderedPage(MatchDeletePage.class);
  }
}
